package lgkj.meicqt20.service;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;
import android.util.Log;

import org.greenrobot.eventbus.EventBus;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import lgkj.meicqt20.bean.MessageEvent;
import lgkj.meicqt20.utils.AllKindsOfConstant;
import lgkj.meicqt20.utils.CommUtils;
import lgkj.meicqt20.utils.HttpUtils;


/**
 * Created by hjx on 2017/6/8.
 */

public class ClientServer {
    private String TAG = "ClientServer";
    private Context mContext;

    private Thread mThread;
    private boolean isConnect;
    private Socket mSocket;
    private String type;
    private long sureTime = 0;

    public ClientServer(Context context) {
        this.mContext = context;
        startClient();
    }

    /**
     * 开始连接
     */
    private void startClient() {
        if (mThread == null || !isConnect) {
            mThread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        isConnect = true;
                        mSocket = new Socket(AllKindsOfConstant.BASE_IP, 7272);
//                        mSocket = new Socket("120.77.213.128", 7272);
                        mSocket.setTcpNoDelay(true);
                        mSocket.setKeepAlive(true);
                        mSocket.setSoTimeout(30 * 1000);
                        sendMsg();
                        String receive = null;
                        Log.i(TAG, "run: " + isServerClose());
                        while (isConnect && (receive = readMsg()) != null) {
                            SendmessageReceived(receive);
                        }
                    } catch (IOException e) {
                        Log.e(TAG, "startClient:" + e.getMessage());
                        isConnect = false;
                        startClient();
                        e.printStackTrace();
                    }
                }
            });
            mThread.start();
        }
    }

    private Long sends;

    private void sendMsg() {
        Log.i(TAG, "sendMsg: " + sends);
        new Timer().schedule(new TimerTask() {
            @Override
            public void run() {
                PrintStream writer;
                try {
                    sends = System.currentTimeMillis();
                    writer = new PrintStream(mSocket.getOutputStream());
                    writer.println(("{\"type\":\"pong\"}"));// 写一个UTF-8的信息
                    writer.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.e(TAG, "run: " + e.getMessage());
                }
            }
        }, 0, 3 * 1000);
    }

    /**
     * 读写数据
     *
     * @return
     */

    private String readMsg() {
        try {
            InputStream is = mSocket.getInputStream();
            byte[] bytes = new byte[1024];
            int length = -1;
            if ((length = is.read(bytes)) != -1) {
                String str = new String(bytes, 0, length);
                Log.i(TAG, "readMsg: " + str + ",len:" + is.available());
                return str;
            } else {
                isConnect = false;
                startClient();
                Log.e(TAG, "readMsg: " + isConnect + "," + startPing() + ",isServerClose:" + isServerClose() + "," + is.available());
            }
        } catch (IOException e) {
            Log.e(TAG, "长连接异常，readMsg():" + e.getMessage());
            isConnect = false;
            startClient();
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 绑定mac
     *
     * @param object
     */
    private void bind(JSONObject object) {
        try {
            Log.i(TAG, "bind: " + isServerClose());
            if (!TextUtils.isEmpty(object.getString("client_id"))) {
                Map<String, String> params = new HashMap<>();
                params.put("client_id", object.getString("client_id"));
                HttpUtils.getHttp(params, AllKindsOfConstant.bindMac, new HttpUtils.HttpCallBack() {
                    @Override
                    public void successHttp(JSONObject jsonObject, int id) {
                        Log.d(TAG, "successHttp: " + jsonObject.toString());
                    }

                    @Override
                    public void errorHttp(String msg) {
                        Log.e(TAG, "errorHttp: " + msg);
                    }
                });
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

    private void SendmessageReceived(String receive) {
        try {
            MessageEvent event = new MessageEvent();
            JSONObject object = new JSONObject(receive);
            type = object.getString("type");
            String order = "";
            if (object.has("user") && object.has("tel")) {
                HttpUtils.user = object.optString("user");
                HttpUtils.tel = object.optString("tel");
            }
            switch (type) {
                case "init":
                    bind(object);
                    break;
                case "control":
                    order = object.getString("data");
                    if (order != null) {
                        switch (order) {
                            case "confirm":
                                order = "sure";
                                break;
                            case "vol-up":
                                type = "voice_add";
                                break;
                            case "vol-down":
                                type = "voice_less";
                                break;
                        }
                    }
                    break;
                case "leave":
                    type = "leave";
                    break;
                default:
                    type = "isNull";
                    break;
            }
//            {"type":"leave","direction":"leave"}
            event.setTagName(type);
            event.setMessage(order);
            EventBus.getDefault().post(event);
            Log.i(TAG, "socket:" + type + ",order:" + order);
        } catch (JSONException e) {
            Log.i("断开", "断开2");
            e.printStackTrace();
        }
    }

    /**
     * 读取数据
     *
     * @param receive
     */
    private void messageReceived(String receive) {
        try {
            JSONObject object = new JSONObject(receive);
            type = object.getString("type");
            String order = "";
            if (object.has("user") && object.has("tel")) {
                HttpUtils.user = object.optString("user");
                HttpUtils.tel = object.optString("tel");
            }
            switch (type) {
                case "init":
                    bind(object);
                    break;
                case "control":
                    order = object.getString("data");
                    if (order != null) {
                        switch (order) {
                            case "confirm":
                                if ((System.currentTimeMillis() - sureTime) > 1500) {
                                    order = "sure";
                                }
                                sureTime = System.currentTimeMillis();
                                break;
                            case "vol-up":
                                order = "voice_add";
                                break;
                            case "vol-down":
                                order = "voice_less";
                                break;
                        }

                        if (!TextUtils.isEmpty(order)) {
                            Log.d(TAG, "messageReceived: 发送：control下，，，，" + order);
                            mContext.sendBroadcast(new Intent("firstOrder").putExtra("order", order));
                        }
                    }
                    break;
                case "newAdvertlist":
                    Log.e(TAG + ".new", "有新的东西,强制退出!");
                    mContext.sendBroadcast(new Intent("firstOrder").putExtra("order", "newAdvertlist"));
                    break;
                case "advert_text":
                    String adText = object.getString("content");
                    Log.e(TAG + ".new", adText);
                    mContext.sendBroadcast(new Intent("firstOrder").putExtra("adText", adText));
                    break;
                case "leave":
                    if (CommUtils.isAutoLevel) {
                        if (AllKindsOfConstant.activitiesList.size() > 0) {
                            Log.i(TAG, "messageReceived: " + AllKindsOfConstant.activitiesList.toString());
                        }
                        for (int i = 0; i < AllKindsOfConstant.activitiesList.size(); i++) {
                            if (AllKindsOfConstant.activitiesList.get(i) != null) {
                                AllKindsOfConstant.activitiesList.get(i).finish();
                                //关闭
                                Log.i(TAG, "自动关闭activity成功~：  " + AllKindsOfConstant.activitiesList.get(i).getLocalClassName());
                            }
                        }
                    }
                    mContext.sendBroadcast(new Intent("firstOrder").putExtra("order", "finish"));
                    break;
                case "ping":
                    break;
            }
            EventBus.getDefault().post(new MessageEvent(receive));
            Log.i(TAG, "socket:" + type + ",order:" + order);
        } catch (JSONException e) {
            Log.i("断开", "断开2");
            e.printStackTrace();
        }
    }

    /**
     * 判断是否断开连接，断开返回true,没有返回false
     *
     * @return
     */
    public Boolean isServerClose() {
        try {
            mSocket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return false;
        } catch (Exception se) {
            return true;
        }
    }

    /**
     * 测试网络连接
     *
     * @return
     */
    public boolean startPing() {
        boolean isnetWork = true;
        try {
            Process p = Runtime.getRuntime().exec("ping -c 1 -w 2 " + AllKindsOfConstant.BASE_IP, null, null);
            int status = p.waitFor();
            if (status == 0) {
                isnetWork = true;
            } else {
                isnetWork = false;
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            isnetWork = false;
        } catch (IOException e) {
            isnetWork = false;
        }
        return isnetWork;
    }
}
